"""
割叶机控制系统 - Windows服务器
功能：Web界面 + 视频代理 + 控制指令下发
"""
from flask import Flask, render_template, jsonify, Response, request
from flask_socketio import SocketIO, emit
import json
import socket
import threading
import time
import logging
from datetime import datetime
from config import NETWORK

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__)
app.config['SECRET_KEY'] = 'leafcutter_2024'
socketio = SocketIO(app, cors_allowed_origins="*", logger=False)

# 全局状态
system_state = {
    'rk3588_connected': False,
    'rk3588_ip': None,
    'video_ok': False,
    'modbus_ok': False,
    'sensor_data': {},
    'last_heartbeat': None
}

tcp_server_running = False
client_socket = None


def start_tcp_server():
    """TCP控制服务器"""
    global tcp_server_running, client_socket, system_state
    
    def tcp_thread():
        global tcp_server_running, client_socket, system_state
        
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        try:
            server_socket.bind(('0.0.0.0', NETWORK['server_port']))
            server_socket.listen(5)
            tcp_server_running = True
            logger.info(f"✅ TCP服务器启动: 0.0.0.0:{NETWORK['server_port']}")
            
            while tcp_server_running:
                try:
                    client_socket, addr = server_socket.accept()
                    system_state['rk3588_ip'] = addr[0]
                    system_state['rk3588_connected'] = True
                    logger.info(f"✅ RK3588连接: {addr}")
                    
                    # 通知前端
                    socketio.emit('system_update', system_state)
                    
                    # 处理数据
                    buffer = ""
                    while tcp_server_running:
                        data = client_socket.recv(4096)
                        if not data:
                            break
                        
                        buffer += data.decode('utf-8', errors='ignore')
                        
                        while '\n' in buffer:
                            line, buffer = buffer.split('\n', 1)
                            if line.strip():
                                try:
                                    msg = json.loads(line.strip())
                                    handle_rk3588_message(msg)
                                except json.JSONDecodeError:
                                    pass
                    
                    # 断开
                    logger.info(f"❌ RK3588断开: {addr}")
                    system_state['rk3588_connected'] = False
                    socketio.emit('system_update', system_state)
                    
                except Exception as e:
                    if tcp_server_running:
                        logger.error(f"连接处理错误: {e}")
        
        except Exception as e:
            logger.error(f"TCP服务器错误: {e}")
        finally:
            tcp_server_running = False
            server_socket.close()
    
    threading.Thread(target=tcp_thread, daemon=True).start()
    time.sleep(0.5)


def handle_rk3588_message(msg):
    """处理RK3588消息"""
    global system_state
    
    msg_type = msg.get('type')
    data = msg.get('data', {})
    
    if msg_type == 'heartbeat':
        system_state['video_ok'] = data.get('video', False)
        system_state['modbus_ok'] = data.get('modbus', False)
        system_state['last_heartbeat'] = datetime.now().isoformat()
        socketio.emit('heartbeat', system_state)
    
    elif msg_type == 'sensors':
        system_state['sensor_data'] = data
        socketio.emit('sensor_update', data)
        logger.info(f"📊 传感器数据: 电压={data.get('voltage')}V, 温度={data.get('generator_temp')}°C")
    
    elif msg_type == 'control_ack':
        # 控制确认
        socketio.emit('control_ack', data)
        logger.info(f"🎮 控制确认: {data.get('action')} = {data.get('value')}")


def send_command(cmd_type, **kwargs):
    """发送命令到RK3588"""
    global client_socket
    
    if not client_socket:
        return False
    
    try:
        cmd = {
            'type': cmd_type,
            'timestamp': datetime.now().isoformat(),
            **kwargs
        }
        json_data = json.dumps(cmd, ensure_ascii=False) + '\n'
        client_socket.send(json_data.encode('utf-8'))
        return True
    except Exception as e:
        logger.error(f"命令发送失败: {e}")
        return False


@app.route('/')
def index():
    """主页"""
    return render_template('index.html')


@app.route('/api/status')
def api_status():
    """系统状态API"""
    return jsonify(system_state)


@app.route('/api/control', methods=['POST'])
def api_control():
    """控制API"""
    try:
        data = request.json
        action = data.get('action')
        value = data.get('value', 0)
        
        success = send_command('control', action=action, value=value)
        
        return jsonify({
            'success': success,
            'message': 'OK' if success else '发送失败'
        })
    except Exception as e:
        return jsonify({'success': False, 'message': str(e)}), 400


@app.route('/video_proxy')
def video_proxy():
    """视频代理 - 纯Python MJPEG"""
    def generate():
        retry_count = 0
        max_retries = 5
        
        while retry_count < max_retries:
            rk3588_ip = system_state.get('rk3588_ip')
            
            if not rk3588_ip:
                logger.warning("等待RK3588连接...")
                time.sleep(2)
                retry_count += 1
                continue
            
            try:
                # 直接连接RK3588的MJPEG流
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(10)
                sock.connect((rk3588_ip, NETWORK['video_port']))
                logger.info(f"✅ 视频连接成功: {rk3588_ip}:{NETWORK['video_port']}")
                
                while True:
                    try:
                        data = sock.recv(16384)
                        if not data:
                            logger.warning("视频流断开")
                            break
                        yield data
                    except socket.timeout:
                        continue
                    except Exception as e:
                        logger.error(f"接收错误: {e}")
                        break
                
                sock.close()
                break  # 成功连接后退出重试循环
                        
            except Exception as e:
                logger.error(f"视频连接失败 (尝试 {retry_count+1}/{max_retries}): {e}")
                retry_count += 1
                if retry_count < max_retries:
                    time.sleep(2)
    
    return Response(
        generate(),
        mimetype='multipart/x-mixed-replace; boundary=frame',
        headers={
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Pragma': 'no-cache',
            'Expires': '0'
        }
    )


@socketio.on('connect')
def handle_connect():
    """WebSocket连接"""
    logger.info("🌐 Web客户端连接")
    emit('system_update', system_state)


@socketio.on('disconnect')
def handle_disconnect():
    """WebSocket断开"""
    logger.info("❌ Web客户端断开")


@socketio.on('send_control')
def handle_control(data):
    """接收前端控制指令"""
    action = data.get('action')
    value = data.get('value', 0)
    
    success = send_command('control', action=action, value=value)
    emit('control_response', {'success': success})


if __name__ == '__main__':
    logger.info("=" * 70)
    logger.info("🚀 割叶机控制系统 - Windows服务器")
    logger.info("=" * 70)
    logger.info(f"📡 TCP端口: {NETWORK['server_port']}")
    logger.info(f"📹 视频端口: {NETWORK['video_port']} (RK3588)")
    logger.info("=" * 70)
    
    start_tcp_server()
    
    logger.info(f"📱 Web界面: http://0.0.0.0:5000")
    logger.info("=" * 70)
    
    socketio.run(app, debug=False, host='0.0.0.0', port=5000)
